package main

import(
	"fmt"
	"time"
	"os"
	"net/http"
	"strconv"
	"encoding/json"
	"github.com/samuel/go-zookeeper/zk"
)

var ServiceName string
var Instance string

type Task struct{
	Id int `json:"id"`
}

type Server struct{
	Ipaddr string `json:ipaddr`
	Port int `json:port`
	Name string `json:name`
	Instance string `json:instance`
}

func HelloServer(w http.ResponseWriter,r *http.Request){
	len := r.ContentLength
	var data []byte = make([]byte, len)
	r.Body.Read(data)

	//var task Task
	//err := json.Unmarshal(data, &task)
	//if(err != nil){
	//	fmt.Println("unmarshal body failed")
	//}

	var response = ServiceName + "[" + Instance + "] has doned task "
	w.Write([]byte(response))
	w.WriteHeader(200)
}

func main() {
	portStr := os.Args[1]
	port, _ := strconv.Atoi(portStr) 
	ServiceName = os.Args[2]
	Instance = os.Args[3]


	var server = Server{"127.0.0.1", port, ServiceName, Instance}
	serverByte, err := json.Marshal(server)
	if(err != nil){
		fmt.Println("Marshal failed");
		return
	}

	hosts := []string{"127.0.0.1:2181"}; 
	conn, _, err := zk.Connect(hosts, time.Second*5);
	if(err != nil){
		fmt.Println("zk connect failed, caused by " + err.Error());
		return
	}
	defer conn.Close();

	var servicePath = "/" + ServiceName
	exist, _, err := conn.Exists(servicePath) 
	if err != nil { 
		fmt.Println("zk Exists failed, caused by " + err.Error());
		return 
	} 
	if(!exist){
		var acls = zk.WorldACL(zk.PermAll);
		_, err := conn.Create(servicePath, []byte{}, 0, acls);
		if(err != nil){
			fmt.Println("zk create failed, caused by " + err.Error());
			return
		}
		fmt.Println(servicePath + " is create")
	}

	var instancePath = servicePath + "/" + Instance + "-"
	var acls = zk.WorldACL(zk.PermAll);
	name, err := conn.Create(instancePath, serverByte, 3, acls);
	if(err != nil){
		fmt.Println("zk create failed, caused by " + err.Error());
		return
	}
	fmt.Println(name + " is create")


	var addr = ":" + portStr
	http.HandleFunc("/" + ServiceName + "/hello", HelloServer)
	err = http.ListenAndServe(addr, nil)
	if(err != nil){
		fmt.Println(addr + " service start failed");
		fmt.Println(err)
		return
	}
}